#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
详细的排列5预测调试脚本
用于诊断排列5 LSTM-CRF 经典模式和序列LSTM 增强模式预测为空的问题
"""

import sys
import os
import torch
import numpy as np
from PyQt5.QtWidgets import QApplication

# 添加项目根目录到路径
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.append(project_root)

def test_plw_data_processor():
    """测试PLWDataProcessor"""
    print("\n" + "="*60)
    print("🧪 测试PLWDataProcessor")
    print("="*60)
    
    try:
        from algorithms.plw_sequence_lstm import PLWDataProcessor
        
        # 创建数据处理器
        csv_file = os.path.join(project_root, 'scripts', 'plw', 'plw_history.csv')
        processor = PLWDataProcessor(csv_file, window_size=10)
        
        print(f"✅ 成功创建PLWDataProcessor")
        print(f" CSV文件: {csv_file}")
        print(f" 窗口大小: {processor.window_size}")
        
        # 测试加载数据
        print("\n🔄 加载和处理数据...")
        X, y = processor.load_and_process_data()
        print(f"✅ 数据加载完成")
        print(f" 特征形状: {X.shape}")
        print(f" 标签形状: {y.shape}")
        
        # 测试获取最近数据
        print("\n🔄 获取最近数据...")
        recent_data = processor.get_recent_data()
        print(f"✅ 最近数据获取完成")
        print(f" 最近数据形状: {recent_data.shape if recent_data is not None else 'None'}")
        if recent_data is not None:
            print(f" 最近数据示例: {recent_data[0, -1, :5].tolist()}")  # 显示最后时间步的5个数字
            
        return recent_data
        
    except Exception as e:
        print(f" PLWDataProcessor测试失败: {e}")
        import traceback
        traceback.print_exc()
        return None

def test_lstm_crf_model_loading():
    """测试LSTM-CRF模型加载"""
    print("\n" + "="*60)
    print("🧪 测试LSTM-CRF模型加载")
    print("="*60)
    
    try:
        from lottery_predictor_app import load_resources_pytorch
        
        # 测试加载排列5模型
        print("\n🔄 加载排列5LSTM-CRF模型...")
        plw_model, blue_model, scaler_X = load_resources_pytorch("plw")
        
        print(f"✅ 模型加载成功")
        print(f" 模型类型: {type(plw_model)}")
        print(f" 蓝球模型: {blue_model}")
        print(f" 缩放器类型: {type(scaler_X)}")
        
        # 检查模型参数
        total_params = sum(p.numel() for p in plw_model.parameters())
        print(f" 模型参数数量: {total_params}")
        
        # 检查模型设备
        device = next(plw_model.parameters()).device
        print(f" 模型设备: {device}")
        
        return plw_model, scaler_X
        
    except Exception as e:
        print(f" LSTM-CRF模型加载失败: {e}")
        import traceback
        traceback.print_exc()
        return None, None

def test_sequence_lstm_model_loading():
    """测试序列LSTM模型加载"""
    print("\n" + "="*60)
    print("🧪 测试序列LSTM模型加载")
    print("="*60)
    
    try:
        from algorithms.plw_sequence_lstm import PLWSequenceLSTM
        
        # 模型路径
        model_path = os.path.join(project_root, 'scripts', 'plw', 'plw_sequence_lstm_model.pth')
        print(f" 模型路径: {model_path}")
        
        if not os.path.exists(model_path):
            print(" 模型文件不存在")
            return None
            
        # 创建模型实例
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        model = PLWSequenceLSTM(input_dim=10, hidden_dim=128, num_layers=3, dropout=0.3).to(device)
        print(f"✅ 成功创建PLWSequenceLSTM模型")
        print(f" 设备: {device}")
        
        # 加载训练好的模型
        print("\n🔄 加载训练好的模型...")
        checkpoint = torch.load(model_path, map_location=device)
        model.load_state_dict(checkpoint['model_state_dict'])
        model.to(device)
        model.eval()
        print(f"✅ 模型加载成功")
        
        # 检查模型参数
        total_params = sum(p.numel() for p in model.parameters())
        print(f" 模型参数数量: {total_params}")
        
        return model
        
    except Exception as e:
        print(f" 序列LSTM模型加载失败: {e}")
        import traceback
        traceback.print_exc()
        return None

def test_model_prediction(model, recent_data, model_name):
    """测试模型预测"""
    print(f"\n" + "="*60)
    print(f"🧪 测试{model_name}预测")
    print("="*60)
    
    try:
        if model is None or recent_data is None:
            print(f" {model_name}或数据为空，无法进行预测")
            return
            
        print(f" 模型类型: {type(model)}")
        print(f" 数据形状: {recent_data.shape}")
        print(f" 数据设备: {recent_data.device if hasattr(recent_data, 'device') else 'CPU'}")
        
        # 确保数据在正确的设备上
        if hasattr(model, 'device'):
            device = next(model.parameters()).device
        else:
            device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
            
        if recent_data.device != device:
            recent_data = recent_data.to(device)
            
        print(f" 模型设备: {device}")
        print(f" 数据设备: {recent_data.device}")
        
        # 进行预测
        print(f"\n 进行{model_name}预测...")
        model.eval()
        
        with torch.no_grad():
            if model_name == "LSTM-CRF":
                # LSTM-CRF预测
                predictions = model(recent_data)
                print(f"✅ 预测完成")
                print(f" 预测结果类型: {type(predictions)}")
                if isinstance(predictions, list):
                    print(f" 预测结果长度: {len(predictions)}")
                    if len(predictions) > 0:
                        print(f" 第一个预测: {predictions[0]}")
                elif isinstance(predictions, torch.Tensor):
                    print(f" 预测结果形状: {predictions.shape}")
                    print(f" 预测结果: {predictions}")
            else:
                # 序列LSTM预测
                predictions, probabilities = model.predict(recent_data)
                print(f"✅ 预测完成")
                print(f" 预测结果类型: {type(predictions)}")
                print(f" 预测结果形状: {predictions.shape}")
                print(f" 预测结果: {predictions}")
                print(f" 概率形状: {probabilities.shape}")
                print(f" 最大概率: {torch.max(probabilities).item():.4f}")
                
    except Exception as e:
        print(f" {model_name}预测失败: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    print("🚀 开始详细的排列5预测调试")
    
    # 创建QApplication实例（如果需要）
    app = QApplication.instance()
    if app is None:
        app = QApplication(sys.argv)
    
    # 测试数据处理器
    recent_data = test_plw_data_processor()
    
    # 测试模型加载
    lstm_crf_model, scaler = test_lstm_crf_model_loading()
    sequence_lstm_model = test_sequence_lstm_model_loading()
    
    # 测试模型预测
    test_model_prediction(lstm_crf_model, recent_data, "LSTM-CRF")
    test_model_prediction(sequence_lstm_model, recent_data, "序列LSTM")
    
    print("\n" + "="*60)
    print("🏁 详细调试完成")
    print("="*60)